package com.vivz.guess.what.vo;

import java.io.Serializable;

public class Clue implements Serializable, Comparable<Clue> {

	private static final long serialVersionUID = 165225881872385815L;

	/**
	 * Symbol to represent a letter in it's right place
	 */
	public static final String _X = "X";

	/**
	 * Symbol to represent a letter NOT in it's right place
	 */
	public static final String _0 = ".";

	/**
	 * Symbol to represent that none of the letters from the guess are in the keyword.
	 */
	public static final String _$ = "-";

	/**
	 * the number of letters in the right place.
	 */
	private final int countX;

	/**
	 * the number of letters NOT in the right place.
	 */
	private final int count0;

	/**
	 * A Clue must consist of the numbers of X's and .'s in it.
	 * 
	 * @param countX
	 *            the number of letters in the right place.
	 * @param count0
	 *            the number of letters NOT in their right place.
	 */
	public Clue(final int countX, final int count0) {
		this.countX = countX;
		this.count0 = count0;
	}

	public boolean hasDash() {
		return 0 == countX + count0;
	}

	public boolean hasCrosses() {
		return countX > 0;
	}

	public boolean hasDots() {
		return count0 > 0;
	}

	public boolean hasCrossesOnly() {
		return countX > 0 && count0 == 0;
	}

	public boolean hasDotsOnly() {
		return count0 > 0 && countX == 0;
	}

	public boolean hasCrossesAndDots() {
		return count0 > 0 && countX > 0;
	}

	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		if (countX == 0 && count0 == 0) {
			sb.append(_$);
		} else {
			// x should always precede 0
			for (int count = 0; count < countX; count++) {
				sb.append(_X);
			}
			for (int count = 0; count < count0; count++) {
				sb.append(_0);
			}
		}
		return sb.toString();
	}

	@Override
	public boolean equals(final Object o) {
		if (o instanceof Clue) {
			final Clue that = (Clue) o;
			return that.count0 == this.count0 && that.countX == this.countX;
		}
		return false;
	}

	@Override
	public int hashCode() {
		int hashCode = 1;
		hashCode = hashCode * 13 + count0;
		hashCode = hashCode * 7 + countX;
		return hashCode;
	}

	@Override
	public int compareTo(final Clue that) {
		if (this.equals(that)) {
			return 0;
		} else if (that == null) {
			return getWeight();
		}
		return this.getWeight() - that.getWeight();
	}

	public int getWeight() {
		return this.countX * 10 + this.count0;
	}

	// //////////////////////
	// GETTERS and SETTERS //
	// //////////////////////

	public int getCountX() {
		return countX;
	}

	public int getCount0() {
		return count0;
	}

}
